Automatic generation produced by ISE Eiffel
indexing
description: "System's entry class derived from CGI_INTERFACE, takes care of requests and sends back responses"
author: "Peizhu Li <lip@student.ethz.ch>"
date: "12.12.2007"
revision: "0.2"
deferred class
REQUEST_DISPATCHER
inherit
CGI_INTERFACE
redefine
make
end
feature -- Attributes
cookie_enabled: BOOLEAN
-- whether cookie is enabled by browser
session_enabled: BOOLEAN
-- whether session support should be enabled
session: SESSION
-- actual session object
config: CONFIG_READER
-- website configuration (handler, default stylesheet, actual session class)
handler_id_string: STRING_8
-- string identifies which handler should be instantiated for actual request
command_string: STRING_8
-- command string that handler need to process
feature {REQUEST_DISPATCHER} -- Attributes
debug_mode: BOOLEAN is True
-- Should exception trace be displayed in case a crash occurs?
session_manager: SESSION_MANAGER
-- object that responsable to retrieve/store session
actual_handler: REQUEST_HANDLER
-- handler that will process actual request
processing_finished: BOOLEAN
-- finished processing, return result
return_page: HTML_PAGE
-- result HTML_PAGE to be sent back to the browser
feature -- creation
make
-- Initiate input data parsing and process information.
local
retried: BOOLEAN
do
session_enabled := True
if not retried then
parse_input
execute
else
if debug_mode then
handle_exception
end
end
rescue
retried := True
retry
end
feature -- dispatching
execute
-- process actual request, send back result html page to the browser.
do
parse_handler_command_string
init_configuration
config.read_configuration (handler_id_string, command_string)
if handler_id_string.is_empty then
handler_id_string := config.default_request
end
if command_string.is_empty then
command_string := config.default_command
end
if session_enabled then
init_session_manager
init_session
end
pre_execute
if not processing_finished then
instantiate_handler
if actual_handler = Void then
process_undefined_request
processing_finished := True
else
return_page := actual_handler.process_request
end
if not processing_finished then
post_execute
end
end
if not response_header.is_complete_header then
response_header.generate_text_header
end
if session_enabled then
save_session
setup_sid_cookie
end
response_header.send_to_browser
response_header.output.put_string (return_page.out)
rescue
io.error.putstring ("crash in `request_dispatcher.execute()' %N")
end
feature {REQUEST_DISPATCHER} -- initialization
set_session_enabled (a_enabled: BOOLEAN)
-- set whether session should be enabled
do
session_enabled := a_enabled
end
process_undefined_request
-- generate result page in case unkown request
do
create {ERROR_PAGE_VIEW} return_page.build_default_not_found_page
end
parse_handler_command_string
-- identify request and command strings ((http://localhost/cgi-bin/zen.cgi?zengarden&action=register -> zengarden, register)
do
create handler_id_string.make_empty
if not input_data.is_empty then
if input_data.has ('&') then
if not input_data.split ('&').i_th (1).has ('=') then
handler_id_string.append ((input_data.split ('&')).i_th (1))
end
else
handler_id_string.append (input_data)
end
if handler_id_string.is_empty and field_defined ("handler_id") then
handler_id_string.append (text_field_value ("handler_id"))
end
end
if field_defined ("cmd") then
create command_string.make_from_string (text_field_value ("cmd"))
else
create command_string.make_empty
end
end
init_configuration
-- read configuration file
local
istart, iend: INTEGER_32
do
istart := script_name.last_index_of ('/', script_name.count) + 1
iend := script_name.last_index_of ('.', script_name.count) - 1
if iend = -1 or iend <= istart then
iend := script_name.count
end
create config.make ("./" + script_name.substring (istart, iend) + ".conf")
end
instantiate_handler
-- based on initialized handler mapping table, lookup and initialize a handler for current request
require
config_is_set: config /= Void
local
handler_type: STRING_8
handler: INTERNAL
type: INTEGER_32
do
if not config.handler.is_empty then
create handler_type.make_from_string (config.handler)
elseif not config.notfound_request.is_empty then
create handler_type.make_from_string (config.notfound_request)
handler_id_string := config.notfound_request
command_string := config.notfound_command
else
create handler_type.make_empty
end
if not handler_type.is_empty then
create handler
type := handler.dynamic_type_from_string (handler_type)
actual_handler ?= handler.new_instance_of (type)
if actual_handler /= Void then
actual_handler.initialize (Current)
end
end
rescue
io.error.putstring ("crash in `lookup_and_instantiate_handler' %N")
end
feature {REQUEST_DISPATCHER} -- pre/post execution
pre_execute
-- common tasks to be executed before starting process user request
-- if necessary, set 'processing_finished' tag and return_page to premature processing
do
end
post_execute
-- common tasks to be executed after request processed
do
end
feature {REQUEST_DISPATCHER} -- session/cookie
init_session_manager
-- init session_manager object
do
create {SESSION_MANAGER_FILE_IMPL} session_manager.make (config.session_files_folder, config.session_expiration, config.session_id_length)
end
init_session
-- retrieve the saved session or create a new session object
local
sid: STRING_8
do
create sid.make_empty
if cookies /= Void and then cookies.has ("sid") then
create sid.make_from_string (cookies.item ("sid"))
session := session_manager.get_session (sid)
if session /= Void and then not session.expired then
cookie_enabled := True
check
cookie_enabled_and_sid_ok: not sid.is_empty
end
else
create sid.make_empty
end
end
if sid.is_empty then
if field_defined ("sid") and not text_field_value ("sid").is_empty then
create sid.make_from_string (Current.text_field_value ("sid"))
else
check
cookie_disabled_and_sid_empty: sid.is_empty
end
create sid.make_from_string (session_manager.generate_session_id)
end
end
check
sid_not_empty: not sid.is_empty
end
session := session_manager.get_session (sid)
if session = Void or (session /= Void and then session.expired) then
create session.make
session.set_session_id (sid)
session.set_expiration_after_seconds (config.session_expiration)
end
ensure
app_session_object_initialized: session /= Void and not session.session_id.is_empty
end
save_session
-- save actual session to session manager
do
session_manager.save_session (session.session_id, session)
end
setup_sid_cookie
-- update cookie in the client
require
session.session_id /= Void and then not session.session_id.is_empty
local
expire: STRING_8
do
expire := session.expiration_time.formatted_out ("ddd, [0]dd-[0]mm-yyyy [0]hh:[0]mi:[0]ss") + " GMT"
response_header.set_cookie ("sid", session.session_id.out, expire, config.application_path, Void, Void)
end
invariant
invariant_clause: True
end -- class REQUEST_DISPATCHER
-- Generated by ISE Eiffel --
For more details: www.eiffel.com